package com.ocean.common.utils.AES;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

/**
 * AES加密解密工具类
 * 支持AES-128-CBC加密模式
 */
public class AESUtil {
    // 加密算法
    private static final String ALGORITHM = "AES";
    // 加密模式和填充方式
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    // 密钥长度必须是16、24或32字节，分别对应AES-128、AES-192、AES-256
    private static final int KEY_SIZE = 16; // 128位密钥

    /**
     * AES加密
     * @param content 待加密内容
     * @param key 密钥，长度必须为16、24或32字节
     * @param iv 初始化向量，长度必须为16字节
     * @return 加密后的Base64字符串
     * @throws Exception 加密过程中可能抛出的异常
     */
    public static String encrypt(String content, String key, String iv) throws Exception {
        // 验证密钥和向量长度
        validateKeyAndIv(key, iv);

        // 创建密钥和向量
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), ALGORITHM);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("UTF-8"));

        // 初始化加密器
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

        // 执行加密并转为Base64
        byte[] encrypted = cipher.doFinal(content.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(encrypted);
    }

    /**
     * AES解密
     * @param encryptedContent 加密后的Base64字符串
     * @param key 密钥，长度必须为16、24或32字节
     * @param iv 初始化向量，长度必须为16字节
     * @return 解密后的原始内容
     * @throws Exception 解密过程中可能抛出的异常
     */
    public static String decrypt(String encryptedContent, String key, String iv) throws Exception {
        // 验证密钥和向量长度
        validateKeyAndIv(key, iv);

        // 创建密钥和向量
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), ALGORITHM);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("UTF-8"));

        // 初始化解密器
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

        // 解密Base64字符串并执行解密
        byte[] decoded = Base64.getDecoder().decode(encryptedContent);
        byte[] decrypted = cipher.doFinal(decoded);
        return new String(decrypted, "UTF-8");
    }

    /**
     * 验证密钥和初始化向量的长度是否符合要求
     */
    private static void validateKeyAndIv(String key, String iv) {
        if (key == null || (key.length() != 16 && key.length() != 24 && key.length() != 32)) {
            throw new IllegalArgumentException("密钥长度必须是16、24或32字节");
        }
        if (iv == null || iv.length() != 16) {
            throw new IllegalArgumentException("初始化向量长度必须是16字节");
        }
    }

    // 测试方法
    public static void main(String[] args) {
        try {
            // 密钥(16字节)和初始化向量(16字节)
            String key = "1234567890abcdef";
            String iv = "fedcba0987654321";
            String content = "15111111111";

            // 加密
            String encrypted = encrypt(content, key, iv);
            System.out.println("加密后: " + encrypted);

            // 解密
            String decrypted = decrypt(encrypted, key, iv);
            System.out.println("解密后: " + decrypted);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
